#include "filemanager.hpp"

void filemanager::show_operations()
{
    cout << "    supportting operations    " << endl;
    cout << "q:     Quit" << endl;
    cout << "cd:    Changing dirctory" << endl;
    cout << "ls:    Listing directory" <<endl;
    cout << "cp:    Copying file" << endl;
    cout << "mkdir: Creatting dirctory" << endl;
    cout << "rmdir: Removing directory" << endl;
    cout << "cpdir: Copying directory" <<endl;
    cout << "help:  Display this information" <<endl;
}

void filemanager::run()
{
    show_operations();
    string command;    //输入的命令
    string sname;      //函数参数（文件夹或路径）
    while (true)
    {
        cout<<endl;
        cout << "Please input the command: " << endl;
        cin>>command;
        if (command=="q")
        {
            cout<<"quit the filemanager"<<endl;
            break;
        }
        else if (command=="mkdir")
        {
            cin>>sname;
            int ret=create_dir(sname.c_str());        
            if (ret==0)
                cout<<sname<<" created sucess!"<<endl;
            else
                cout<<sname<<" exist!"<<endl;
        }   
        else if (command=="cd")
        {
            cin>>sname;    
            int ret=change_dir(sname.c_str());
            if (ret==0)
                cout<<"Change successfully"<<endl;
            else
                cout<<"No this path"<<endl;
        }
        else if (command=="rmdir")
        {
            cin>>sname;
            int ret=remove_dir(sname.c_str());
            if (ret==0)
                cout<<"Remove successfully!"<<endl;
            else
                cout<<"No rhis path"<<endl;
        }
        else if (command=="ls")
        {
            cin>>sname;
            int ret=list_dir(sname.c_str());
            if (ret!=0)
                cout<<"No this path"<<endl;
        }
        else if (command=="cp")
        {
            string tocopy;
            cin>>sname>>tocopy;
            int ret=copy(sname.c_str(),tocopy.c_str());
            if (ret==0)
                cout<<"Copy successfully!"<<endl;
            else
                cout<<"No this file!"<<endl;
        }
        else if (command=="cpdir")
        {
            string tocopy;        //目标文件夹
            cin>>sname>>tocopy;
            int ret=copy_dir(sname.c_str(),tocopy.c_str());
            if (ret==0)
                cout<<"Copy successfully!"<<endl;
            else
                cout<<"No this path"<<endl;
        }               
        else if (command=="help")
        {
            show_operations();
        }

        else
        {
            cout << "Please input a correct file operation command!" << endl;
        }
    }
}

int filemanager::create_dir(const char* dir)
{
    DIR* mydir = nullptr;
    mydir = opendir(dir);
    if (mydir==nullptr)
    {
        int ret = mkdir(dir,S_IRWXU);
        if (ret==0)
            return 0;
        else
            return -1;
    }
    else
        return -1;
}

int filemanager::change_dir(const char* path)
{
    int ret = chdir(path);
    return ret;
}

int filemanager::remove_dir(const char* path)
{
    DIR* mydir = nullptr;
    mydir = opendir(path);
    if (mydir==nullptr)
        return -1;
    else
    {
        int ret=rmdir(path);
        if (ret==0)
            return 0;
        else
        {
            while (1)
            {
                dirent* files = readdir(mydir);
                if (files==nullptr)
                {
                    rmdir(path);
                    return 0;
                }
                if (strcmp(files->d_name,".")&&strcmp(files->d_name,".."))
                {
                    string zidir=string(path)+"/"+string(files->d_name);
                    int pp=remove(zidir.c_str());
                    if (pp!=0){
                        remove_dir(zidir.c_str());
                    }
                }
            }
        }
    }
}

int filemanager::list_dir(const char* path)
{
    DIR* mydir = opendir(path);
    if (mydir==nullptr)
        return -1;
    dirent* dirlist;
    while (1)
    {
        dirlist = readdir(mydir);
        if (dirlist==NULL)
            break;
        if (!strcmp(dirlist->d_name,".")||!strcmp(dirlist->d_name,".."))
            continue;
        cout<<dirlist->d_name<<endl;
    }
    return 0;
}

int filemanager::copy(const char* file,const char* path)
{
    ifstream in;
    ofstream out;
        
    string pp=string(path)+"/"+file;

    in.open(file,ios::in);
    if (!in.good())
        return -1;
    out.open(pp.c_str(),ios::out);

    out<<in.rdbuf();

    in.close();
    out.close();
    return 0;
}

int filemanager::copy_dir(const char* path1, const char* path2)
{
    DIR* mydir = nullptr;

    mydir = opendir(path1);
    if (mydir==nullptr)
        return -1;
    mkdir(path2,S_IRWXU);

    dirent* files;
    while (1)
    {
        
        files = readdir(mydir);
        if (files==nullptr)
            return 0;
        if (strcmp(files->d_name,".")&&strcmp(files->d_name,".."))
        {
            cout<<files->d_type;
            if (files->d_type==4)
            {
                //复制文件夹
                string ppp=string(path2)+"/"+string(files->d_name);
                create_dir(ppp.c_str());
                string pp1 = string(path1)+"/"+string(files->d_name);
                string pp2 = string(path2)+"/"+string(files->d_name);
                copy_dir(pp1.c_str(),pp2.c_str());
            }
            else
            {
                //复制文件
                ifstream in;
                ofstream out;
                string pp2 = string(path2)+"/"+string(files->d_name);
                string pp1 = string(path1)+"/"+string(files->d_name);

                in.open(pp1.c_str(),ios::in);
                out.open(pp2.c_str(),ios::out);

                out<<in.rdbuf();

                in.close();
                out.close();
            }
        }
    }
}